﻿// <copyright file="Win32DoxygenOutputParser.cs" company="Horiba Medical">
//     Copyright (c) Horiba Medical. All rights reserved.
// </copyright>
// <summary>
//     Parses outputs from a Win32 version Doxygen warning log.
// </summary>

namespace DoxyOutParser.Parser
{
	using System;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.IO;

	/// <summary>
	/// Provide the functions and methods enabling the parsing of a warning log generated by the Win32 version of Doxygen.
	/// </summary>
	public class Win32DoxygenOutputParser : IOutputParser
	{
		/// <summary>
		/// Parses a warning log for entries.
		/// </summary>
		/// <param name="outputFile">Path and name of the file to parse.</param>
		/// <param name="filter">Filter to apply on the displayed items.</param>
		/// <returns>A list of output entries found in the log file.</returns>
		public OutputEntryCollection Parse(string outputFile, string filter)
		{
			OutputEntryCollection entryList = new OutputEntryCollection();
			try
			{
				// Using of StreamReader to parse the file
				StreamReader cycleStreamReader = new StreamReader(outputFile);
				string line = cycleStreamReader.ReadLine();
				string[] paramSeparators = { ":" };

				while (line != null)
				{
					if (line.Length == 0)
					{
						line = cycleStreamReader.ReadLine();
					}
					else
					{
						string nextLine = cycleStreamReader.ReadLine();

						if (nextLine != null)
						{
							if ((nextLine.StartsWith("D", StringComparison.Ordinal) || nextLine.StartsWith("C", StringComparison.Ordinal)) && nextLine.Contains("Warning"))
							{
								string[] entryData = line.Split(paramSeparators, 5, StringSplitOptions.RemoveEmptyEntries);
								OutputEntry newEntry = CreateDoxygenOutputEntryFromEntryData(entryData);
								if (filter.Length != 0)
								{
									if (newEntry.FileNameAndPath.ToString().Contains(filter))
									{
										entryList.Add(newEntry);
									}
								}
								else
								{
									entryList.Add(newEntry);
								}

								line = nextLine;
							}
							else
							{
								line += "\r\n" + nextLine;
							}
						}
						else
						{
							string[] entryData = line.Split(paramSeparators, 5, StringSplitOptions.RemoveEmptyEntries);
							OutputEntry newEntry = CreateDoxygenOutputEntryFromEntryData(entryData);
							if (filter.Length != 0)
							{
								if (newEntry.FileNameAndPath.ToString().Contains(filter))
								{
									entryList.Add(newEntry);
								}
							}
							else
							{
								entryList.Add(newEntry);
							}

							// Set line to null because nextLine has been seen null already
							line = null;
						}
					}
				}
			}
			catch
			{
				throw;
			}

			return entryList;
		}

		/// <summary>
		/// Creates a Doxygen OutputEntry object from a warning log entry.
		/// </summary>
		/// <param name="entryData">The entry to modify.</param>
		/// <returns>The created output entry.</returns>
		private static OutputEntry CreateDoxygenOutputEntryFromEntryData(string[] entryData)
		{
			OutputEntry newEntry = new OutputEntry();
			if (entryData.Length == 5)
			{
				newEntry.FileNameAndPath = entryData[0] + ":" + entryData[1].Replace("/", "\\");
				newEntry.Line = entryData[2];
				newEntry.MessageType = entryData[3];
				newEntry.MessageDetails = entryData[4];
			}
			else
			{
				// TODO launch an exception if entryData.Lenght is different of 5
			}

			return newEntry;
		}
	}
}
